<?php
use Firebase\JWT\JWT;

require_once 'php-jwt/src/JWT.php';

function getToken($type, $params = []): array
{
    //https://www.jianshu.com/p/61d2185b6fd9
    //https://www.jianshu.com/p/9f94d2c3f625
    //headers.Authorization = `Bearer ${token}` 为什么要加Bearer https://blog.csdn.net/weixin_43416349/article/details/120936303

    //token自动续期方案，生成的token中不带有过期时间，token的过期时间由redis进行管理，在redis中单独为每个JWT设置过期时间，每次访问时刷新JWT的过期时间
    //更新用户密码时需要重新生成新的token，并将新的token返回给前端，由前端更新保存在local storage中的token，同时更新存储在redis中的token，这样实现可以避免用户重新登陆，用户体验感不至于太差
    //token自动续期：
    //为了不频繁操作redis，只有当离过期时间只有30分钟时才更新过期时间
    //http://itindex.net/detail/60912-jwt-token
    //https://wenku.baidu.com/view/79ba223c68d97f192279168884868762caaebb8a.html
    //https://wenku.baidu.com/view/26ab3ca380d049649b6648d7c1c708a1284a0ab0?aggId=79ba223c68d97f192279168884868762caaebb8a
    $id = 123456;
    $host = 'www.baidu.com';
    $time = time();

    /*{
      "iss": "admin",     //该JWT的签发者
      "iat": 1535967430,    //签发时间
      "exp": 1535974630,    //过期时间
      "nbf": 1535967430,     //该时间之前不接收处理该Token
      "sub": "www.admin.com",  //面向的用户
      "jti": "9f10e796726e332cec401c569969e13e"  //该Token唯一标识
    }*/

    /*iss: jwt签发者
    sub: jwt所面向的用户
    aud: 接收jwt的一方
    exp: jwt的过期时间，这个过期时间必须要大于签发时间
    nbf: 定义在什么时间之前，该jwt都是不可用的
    iat: jwt的签发时间
    jti: jwt的唯一身份标识，主要用来作为一次性token,从而回避重放攻击*/

    $params += [
        'iss' => $host, //签发者 可以为空
        'aud' => $host,//面象的用户，可以为空
        'iat' => $time,//签发时间
        'nbf' => $time, //在什么时候jwt开始生效
        'exp' => strtotime('+ 3hour'), //token 过期时间
        'data' => ['user_id' => 123, 'mobile' => 132], //记录的uid的信息，这里是自已添加上去的，如果有其它信息，可以再添加数组的键值对
    ];

    //$params['jti'] = time().'123';
    $token = JWT::encode($params, '123456');
    
    return compact('token', 'params');
}


 $tokenInfo = getToken('user');

echo "<pre>";
var_dump($tokenInfo);die;


function parseToken($jwt)
{
    JWT::$leeway = 60;
    
    $data = JWT::decode($jwt, '123456', array('HS256'));
    return $data;
    //$model = new self();
    //return [$model->where($model->getPk(), $data->jti->id)->find(), $data->jti->type];
}

$user = parseToken('eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ3d3cuYmFpZHUuY29tIiwiYXVkIjoid3d3LmJhaWR1LmNvbSIsImlhdCI6MTU5MzMzOTMwNSwibmJmIjoxNTkzMzM5MzA1LCJleHAiOjE1OTMzNTAxMDUsImp0aSI6eyJpZCI6MTIzLCJ0eXBlIjoidXNlciJ9fQ.2QsQSwVNrrPDfLBVm5f5zIYk-cQlw2RPHPD_2Jvy824');
echo "<pre>";
var_dump($user);die;


/*public function check(){
    $jwt = Request::header('Authorization');  //上一步中返回给前端的token
    $jwt = substr($jwt,7);
    $key = "xxxxxxxxxxxxxxxxxxxxxxx";  //上一个方法中的 $key 本应该配置在 config文件中的
    $info = JWT::decode($jwt,$key,["HS256"]); //解密jwt
    return json($info);
}*/